#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = (l); i <= (r); ++i)
#define per(i, r, l) for (int i = (r); i >= (l); --i)
#define ls (num << 1)
#define rs (num << 1 | 1)
const int inf = INT_MAX, df = 2e4 + 7, N = 5e5 + 7, B = 16, K = 32 ;/*相对较好的参数*/
int i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
long long ma[9][df << 1];
long long tag[9][df << 1];
int mx[9][df << 1], mn[9][df << 1];
int a[N];
long long sum[9][df << 1];
long long lb[9], rb[9]; /*这里是倍增分块的上界和下界*/
/*
ma:区间有几个数
sum:区间和
mx:区间最大值
mn:区间最小值
tag:懒标记
*/
void pushup(int blk, int num)
{
	ma[blk][num] = ma[blk][ls] + ma[blk][rs];
	sum[blk][num] = sum[blk][ls] + sum[blk][rs];
	mx[blk][num] = max(mx[blk][ls], mx[blk][rs]);
	mn[blk][num] = min(mn[blk][ls], mn[blk][rs]);
	return;
}
/*线段树上传信息*/
void pushdown(int blk, int num)
{
	if (!tag[blk][num])
		return;
	tag[blk][ls] += tag[blk][num] * (ma[blk][ls] != 0), tag[blk][rs] += tag[blk][num] * (ma[blk][rs] != 0);
	if (ma[blk][ls])
		sum[blk][ls] -= tag[blk][num] * ma[blk][ls], mx[blk][ls] -= tag[blk][num], mn[blk][ls] -= tag[blk][num];
	if (ma[blk][rs])
		sum[blk][rs] -= tag[blk][num] * ma[blk][rs], mx[blk][rs] -= tag[blk][num], mn[blk][rs] -= tag[blk][num];
	tag[blk][num] = 0;
	return;
}
/*线段树下传标记*/
int getblk(int x)
{
	int now = 1;
	while (x > rb[now])
		now++;
	return now;
}
/*x在第几个值域块*/
void blk_pushdown(int blk, int le, int rig, long long &x)
{
	if (!x)
		return;
	rep(i, le, rig) if (a[i] >= lb[blk] && a[i] <= rb[blk]) a[i] -= x;
	x = 0;
	return;
}
/*线段树的叶子节点向序列下传标记*/
void blk_pushup(int blk, int le, int rig, int num)
{
	ma[blk][num] = 0, sum[blk][num] = 0, mx[blk][num] = 0, mn[blk][num] = inf;
	rep(i, le, rig)
	{
		if (a[i] >= lb[blk] && a[i] <= rb[blk])
		{
			ma[blk][num]++;
			sum[blk][num] += a[i];
			mx[blk][num] = max(mx[blk][num], a[i]);
			mn[blk][num] = min(mn[blk][num], a[i]);
		}
	}
	return;
}
/*把序列的信息上传到线段树的叶子节点上*/
void insert(int blk, int num, int le, int rig, int p, int x)
{
	if (rig - le + 1 <= K)
	{
		blk_pushdown(blk, le, rig, tag[blk][num]);
		a[p] = x;
		blk_pushup(blk, le, rig, num);
		return;
	}
	int mid = (le + rig) >> 1;
	pushdown(blk, num);
	if (p <= mid)
		insert(blk, ls, le, mid, p, x);
	else
		insert(blk, rs, mid + 1, rig, p, x);
	pushup(blk, num);
	return;
}
/*线段树插入节点*/
void blk_upd(int blk, int le, int rig, int x)
{
	rep(i, le, rig) if (a[i] >= lb[blk] && a[i] <= rb[blk] && a[i] > x)
	{
		a[i] -= x;
		if (a[i] < lb[blk])
		{
			insert(getblk(a[i]), 1, 1, n, i, a[i]);
		} /*插入另一个块的线段树*/
	}
	return;
}
/*块内暴力执行1号操作*/
void blk_qry(int blk, long long &ans, int &maxn, int &minn, int le, int rig, int l, int r)
{
	rep(i, max(le, l), min(rig, r))
	{
		if (a[i] >= lb[blk] && a[i] <= rb[blk])
		{
			ans += a[i], maxn = max(maxn, a[i]), minn = min(minn, a[i]);
		}
	}
	return;
}
/*块内暴力执行查询*/
void upd(int blk, int num, int le, int rig, int l, int r, int x)
{
	if (mx[blk][num] <= x)
		return; /*小于就跳过*/
	if (rig - le + 1 <= K)
	{
		blk_pushdown(blk, le, rig, tag[blk][num]);
		l = max(l, le), r = min(r, rig);
		blk_upd(blk, l, r, x);
		blk_pushup(blk, le, rig, num);
		return;
	} /*到达叶子暴力修改*/
	if (le >= l && rig <= r && mn[blk][num] - lb[blk] >= x)
	{
		sum[blk][num] -= x * ma[blk][num], mn[blk][num] -= x, mx[blk][num] -= x; /*直接打懒标记*/
		tag[blk][num] += x;
		return;
	}
	int mid = (le + rig) >> 1;
	pushdown(blk, num);
	if (l <= mid)
		upd(blk, ls, le, mid, l, r, x);
	if (r > mid)
		upd(blk, rs, mid + 1, rig, l, r, x);
	pushup(blk, num);
	return;
}
/*线段树上执行操作*/
void qry(long long &ans, int &maxn, int &minn, int blk, int num, int le, int rig, int l, int r)
{
	if (le >= l && rig <= r)
	{
		ans += sum[blk][num], maxn = max(maxn, mx[blk][num]), minn = min(minn, mn[blk][num]);
		return;
	} /*叶子节点暴力查询*/
	if (rig - le + 1 <= K)
	{ /*完全包含，直接统计*/
		blk_pushdown(blk, le, rig, tag[blk][num]);
		blk_qry(blk, ans, maxn, minn, le, rig, l, r);
		blk_pushup(blk, le, rig, num);
		return;
	}
	int mid = (le + rig) >> 1;
	pushdown(blk, num); /*注意及时下传和上传*/
	if (l <= mid)
		qry(ans, maxn, minn, blk, ls, le, mid, l, r);
	if (r > mid)
		qry(ans, maxn, minn, blk, rs, mid + 1, rig, l, r);
	pushup(blk, num);
	return;
}
inline int read()
{
	int x = 0, y = 1;
	char ch = getchar();
	while (ch > '9' || ch < '0')
		y = (ch == '-') ? -1 : 1, ch = getchar();
	while (ch >= '0' && ch <= '9')
		x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
	return x * y;
}
void fwrite(int x)
{
	if (x > 9)
		fwrite(x / 10);
	putchar(x % 10 + '0');
	return;
} /*最好加上快读快输*/
void llfwrite(long long x)
{
	if (x > 9)
		llfwrite(x / 10);
	putchar(x % 10 + '0');
	return;
}
int main()
{
	rep(j, 1, 8) rep(i, 0, df * 2 - 2) mn[j][i] = inf, mx[j][i] = 0;/*初始化*/
	n = read(), q = read();
	rep(i, 1, 8) lb[i] = rb[i - 1] + 1, rb[i] = lb[i] * B - 1;/*预处理*/
	rep(i, 1, n) a[i] = x = read(), insert(getblk(x), 1, 1, n, i, x);
	int op = 0, l = 0, r = 0, x = 0, lastans = 0, maxn = 0, minn = 0;
	long long ans = 0;
	while (q--)
	{
		op = read(), l = read() ^ lastans, r = read() ^ lastans;
		if (op == 1)
		{
			x = read() ^ lastans;/*强制在线*/
			rep(i, 1, 8) if (rb[i] >= x) upd(i, 1, 1, n, l, r, x);
		}
		else
		{
			ans = 0, maxn = 0, minn = inf;
			rep(i, 1, 8) qry(ans, maxn, minn, i, 1, 1, n, l, r);
			llfwrite(ans), putchar(' '), fwrite(minn), putchar(' '), fwrite(maxn), putchar('\n');
			//lastans = ans % 1048576;
		}
	}
}
